package jude.java.util;

import java.lang.reflect.Array;

public class Log {
	public static final int LOG_LEVEL_V = 0X01;
	public static final int LOG_LEVEL_D = 0X02;
	public static final int LOG_LEVEL_I = 0X04;
	public static final int LOG_LEVEL_W = 0X08;
	public static final int LOG_LEVEL_E = 0X10;
	
	public static final int LOG_LEVEL_NONE = 0;
	public static final int LOG_LEVEL_ALL = 0X1F;
	
	private static int logLevel = LOG_LEVEL_ALL;
	private static String THIS_CLASS = Log.class.getName();
	
	public static void print(Object... os) {
		StringBuilder sb = new StringBuilder();
		for (int i = 0; i < os.length; i++) {
			if (i != 0)
				sb.append(", ");
			sb.append(os[i]);
		}
		System.out.print(sb.toString());
	}
	
	public static void v() {
		v(null);
	}
	public static void v(Object o) {
		if ((logLevel & LOG_LEVEL_V) != 0)
			log(LOG_LEVEL_V, o);
	}

	public static void d() {
		d(null);
	}
	public static void d(Object o) {
		if ((logLevel & LOG_LEVEL_D) != 0)
			log(LOG_LEVEL_D, o);
	}

	public static void i() {
		i(null);
	}
	public static void i(Object o) {
		if ((logLevel & LOG_LEVEL_I) != 0)
			log(LOG_LEVEL_I, o);
	}

	public static void w() {
		w(null);
	}
	public static void w(Object o) {
		if ((logLevel & LOG_LEVEL_W) != 0)
			log(LOG_LEVEL_W, o);
	}

	public static void e() {
		e(null);
	}
	public static void e(Object o) {
		if ((logLevel & LOG_LEVEL_E) != 0)
			log(LOG_LEVEL_E, o);
	}
	
	private static String[] getCaller() {
		Throwable ex = new Throwable();
		StackTraceElement[] trace = ex.getStackTrace();
		for (int i = 3; i< trace.length; i++) {
			String className = trace[i].getClassName();
			if (THIS_CLASS.equals(className))
				continue;
			className = className.substring(className.lastIndexOf('.') + 1);
			return new String[] {className, trace[i].getMethodName(), String.valueOf(trace[i].getLineNumber())};
		}
		return new String[] {null, null, null};
	}
	
	private static void log(int type, Object o) {
		String[] caller = getCaller();
		String tag = null;
		String msg = null;
		tag = "[" + caller[0] + "]";
		msg = caller[2] + '[' + caller[1] + ']';
		if (o == null || o instanceof Throwable) {
			if (o != null && type == LOG_LEVEL_E)
				msg += '\n' + ((Throwable)o).toString();//android.util.Log.getStackTraceString((Throwable)o);
		} else if (o.getClass().isArray()) {
			int len = Array.getLength(o);
			String name = o.getClass().getSimpleName();
			name = name.substring(0, name.length() - 1) + len + "]";
			msg += name;
			Object item;
			if (len > 0 && (item = Array.get(o, 0)) != null) {
				msg += ": " + item.toString();
			}
		} else {
			msg += String.valueOf(o);
		}
		log(type, tag, msg);
	}
	
	private static void log(int type, String tag, String msg) {
		System.out.println(tag + '\t' + msg);
//		android.util.Log.println(type, tag, msg);
		
/*		org.apache.commons.logging.Log log = LogFactory.getLog(tag);
		switch (type) {
		case LOG_LEVEL_E:
			log.fatal(msg);
			break;
		case LOG_LEVEL_W:
			log.error(msg);
			break;
		case LOG_LEVEL_I:
			log.info(msg);
			break;
		case LOG_LEVEL_D:
			log.debug(msg);
			break;
		case LOG_LEVEL_V:
			log.trace(msg);
			break;
		default:
			break;
		}
*/
	}
	
	public static void setLogLevel(int level) {
		logLevel = level & LOG_LEVEL_ALL;
	}
	
	private Log() {
	}
}
